﻿using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;

namespace AuthenticationCenter.Service
{
    /// <summary>
    /// 非对称可逆加密
    /// </summary>
    public class RssJwtService : IJwtService
    {
        private readonly JwtTokenOptions _jwtTokenOptions;
        public RssJwtService(IOptions<JwtTokenOptions> jwtTokenOptions)
        {
            _jwtTokenOptions = jwtTokenOptions.Value;
        }

        public string GetToken(string name, string password)
        {
            //使用加密解密Key 非对称
            string keyDir = Directory.GetCurrentDirectory();
            if (RsaHelper.TryGetKeyParameters(keyDir, true, out var keyParams) == false)
            {
                keyParams = RsaHelper.GenerateAndSaveKey(keyDir);
            }

            // 有效载荷，尽量避免敏感信息
            var claims = new[]
            {
                new Claim(ClaimTypes.Name, name),
                new Claim("NickName", name),
                new Claim(ClaimTypes.Role, "Admin"),
                new Claim("CustomField", "CustomValue From Rsa"),
                new Claim("jti", Guid.NewGuid().ToString()), //用来标识 Token
            };

            // nuget 引入：Microsoft.IdentityModel.Tokens

            var key = new RsaSecurityKey(keyParams);

            SigningCredentials credentials = new SigningCredentials(key, SecurityAlgorithms.RsaSha256Signature);

            // nuget 引入：System.IdentityModel.Tokens.Jwt
            var jwtSecurityToken = new JwtSecurityToken(
                issuer: _jwtTokenOptions.Issuer,
                audience: _jwtTokenOptions.Audience,
                claims: claims,
                notBefore: DateTime.Now,
                expires: DateTime.Now.AddMinutes(5),
                signingCredentials: credentials
                );

            var handler = new JwtSecurityTokenHandler();

            var token = handler.WriteToken(jwtSecurityToken);

            return token;
        }
    }
}
